﻿using System.Collections.Generic;
using System.Linq;

namespace Pap.Data
{
    /// <summary>
    /// 
    /// </summary>
    public partial class User : IUser
    {
        #region IUser Members

        /// <summary>
        /// Gets the roles.
        /// </summary>
        public IEnumerable<IRole> Roles
        {
            get { return this.UsersRoles.Select(t => t.Role).OfType<IRole>(); }
        }

        /// <summary>
        /// Gets the permissions.
        /// </summary>
        public IEnumerable<IPermission> Permissions
        {
            get
            {
                return this.UsersRoles.SelectMany(t => t.Role.RolesPermissions.Select(p => p.Permission)).OfType<IPermission>();
            }
        }

        /// <summary>
        /// Gets the permissions.
        /// </summary>
        public IEnumerable<IProject> Projects
        {
            get
            {
                return this.UsersProjects.Select(t => t.Project).OfType<IProject>();
            }
        }

        /// <summary>
        /// Gets the users roles.
        /// </summary>
        IEnumerable<IUsersRole> IUser.UsersRoles
        {
            get { return this.UsersRoles.OfType<IUsersRole>(); }
        }

        /// <summary>
        /// Gets the project.
        /// </summary>
        IEnumerable<IUsersProject> IUser.UserProjects
        {
            get { return this.UsersProjects.OfType<IUsersProject>(); }
        }

        /// <summary>
        /// Gets the users committees.
        /// </summary>
        IEnumerable<IUsersCommittees> IUser.UsersCommittees
        {
            get { return this.UsersCommittees.OfType<IUsersCommittees>(); }
        }

        /// <summary>
        /// Gets the customer loans.
        /// </summary>
        IEnumerable<ICustomerLoan> IUser.CustomerLoans
        {
            get { return this.CustomerLoans.OfType<ICustomerLoan>(); }
        }

        /// <summary>
        /// Authenticates the specified password.
        /// </summary>
        /// <param name="password">The password.</param>
        /// <returns></returns>
        public bool Authenticate(string password)
        {
            return this.Password == Password;
        }

        /// <summary>
        /// Changes the roles.
        /// </summary>
        /// <param name="newRoleList">The new role list.</param>
        public void ChangeRoles(IEnumerable<IRole> newRoleList)
        {
            var deleted = this.UsersRoles.Where(r => !newRoleList.Select(rr => rr.RoleID).Contains(r.RoleID)).ToList();
            var inserted = newRoleList.Where(r => !this.UsersRoles.Select(rr => rr.RoleID).Contains(r.RoleID));

            foreach (var item in deleted)
            {
                this.UsersRoles.Remove(item);
            }

            foreach (var item in inserted)
            {
                this.UsersRoles.Add(new UsersRole { UserID = this.UserID, RoleID = item.RoleID });
            }
        }

        /// <summary>
        /// Changes the committees.
        /// </summary>
        /// <param name="newCommitteeList">The new committee list.</param>
        public void ChangeCommittees(IEnumerable<ICommittee> newCommitteeList)
        {
            var deleted = this.UsersCommittees.Where(ct => !newCommitteeList.Select(c => c.CommitteeID).Contains(ct.CommitteeID)).ToList();

            var inserted = newCommitteeList.Where(c => !this.UsersCommittees.Select(ct => ct.CommitteeID).Contains(c.CommitteeID));

            foreach (var item in deleted)
            {
                this.UsersCommittees.Remove(item);
            }

            foreach (var item in inserted)
            {
                this.UsersCommittees.Add(new UsersCommittee { UserID = this.UserID, CommitteeID = item.CommitteeID });
            }
        }



        /// <summary>
        /// Changes the Projects.
        /// </summary>
        /// <param name="newProjectList">The new Project list.</param>
        public void ChangeProjects(IEnumerable<IProject> newProjectList)
        {
            var deleted = this.UsersProjects.Where(ct => !newProjectList.Select(c => c.ProjectID).Contains(ct.ProjectID)).ToList();

            var inserted = newProjectList.Where(c => !this.UsersProjects.Select(ct => ct.ProjectID).Contains(c.ProjectID));

            foreach (var item in deleted)
            {
                this.UsersProjects.Remove(item);
            }

            foreach (var item in inserted)
            {
                this.UsersProjects.Add(new UsersProject { UserID = this.UserID, ProjectID = item.ProjectID });
            }
        }

        #endregion
    }
}
